package main

import (
	"fmt"
	"io/ioutil"
	"os"
	"os/exec"
	"path"
	"strconv"
	"syscall"
)

// 挂载memory subsystem的hierachy的根目录位置
const cgroupMemoryHierachMount = "sys/fs/cgroup/memory"

func main() {
	fmt.Println(os.Args[1])
	if os.Args[1]=="/proc/self/exe"{
		// 容器进程
		fmt.Println("")
		cmd := exec.Command("sh","-c",`stress --vm-bytes 200m --vm-keep -m 1`)
		cmd.SysProcAttr = &syscall.SysProcAttr{}
		cmd.Stdin = os.Stdin
		cmd.Stdout = os.Stdout
		cmd.Stderr = os.Stderr
		if err := cmd.Run();err!=nil{
			fmt.Println(err)
			os.Exit(1)
		}
		cmd = exec.Command("/proc/self/exe")
		cmd.SysProcAttr = &syscall.SysProcAttr{
			Cloneflags: syscall.CLONE_NEWUTS | syscall.CLONE_NEWIPC|syscall.CLONE_NEWPID,
		}
		cmd.Stdin = os.Stdin
		cmd.Stdout = os.Stdout
		cmd.Stderr = os.Stderr
		if err := cmd.Start();err!= nil{
			fmt.Println("ERROR",err)
			os.Exit(1)
		}else {
			// 得到fork 出来的进程映射在外部命名空间的pid
			fmt.Println("%v",cmd.Process.Pid)

			// 在默认创建挂载了 memory  subsystem的Hiearchy 上创建cgroup
			os.Mkdir(path.Join(cgroupMemoryHierachMount,"testmemorylimit"),0755)

			// 将容器进程加入到这个cgroup中
			ioutil.WriteFile(path.Join(cgroupMemoryHierachMount,"testmemorylimit","tasks"),[]byte(strconv.Itoa(cmd.Process.Pid)),0644)

			// 限制cgroup进程使用
			ioutil.WriteFile(path.Join(cgroupMemoryHierachMount,"testmemorylimit","memory.limit_in_bytes"),[]byte("100m"),0644)

			cmd.Process.Wait()

		}

	}else {
		fmt.Println("ta in error")
	}
}
